/**
*
* @file
*		heap_julia
*
* @brief
*		Heap implementation by julia
*/

#include "../../api/heap.h"
#include <vector> 
#include <malloc.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <Windows.h>

using namespace std;

#ifdef _DEBUG
enum history_enum
{
 constructor_code,
 alloc_code,
 free_code,
 free_all_code,
 error
};

struct j_
{
	size_t total;
	heap876::alloc_flags flag;
};

struct s_
{
	 size_t sz;
	 unsigned int tag;
};

union history_union
{
        j_ constr;
		s_ alloc__;
		void* free__;
		unsigned int free_all__;
		char* message;
};

struct history_struct
{
    history_enum code_of_func;
    history_union uni;
	history_struct(history_enum code_of_func_,history_union uni_) : code_of_func(code_of_func_), uni(uni_) {}
};
#endif
/**
* basic interface
*/
class heap_julia: public heap876
{
private:
	static const int mutexed_part_=5;
	static const int mutex_amount_=mutexed_part_+2;
	int mutexed_part;
	int mutex_amount;
	HANDLE MutexArr[mutex_amount_];
			size_t total_limit_;

	#ifdef _DEBUG
	void control(int code);
#endif
	// current volume of distributed memory
	size_t alloc_sz;
	#ifdef _DEBUG
    vector<history_struct> history;
    #endif
	vector<bool> bitmask;
	vector<bool> beginnings; // it is necessary to know where beginnnings and endings of the allocated pieces  are in order to implement "free" function
	vector<bool> ends;
	unsigned int* tagArray;
	int size_of_block;
    char* memory; 
	FILE * log;

public:
	heap_julia( size_t total, alloc_flags flag);
	virtual ~heap_julia();
	
	void dump_history();
	virtual void*	alloc( size_t sz, unsigned int tag );
	void print_all();
    virtual void free( void* ptr );
	virtual void free_all( unsigned int tag );
	virtual size_t get_occupancy() const { return alloc_sz; };
	void is_hungry();
	size_t get_volume();
};
